<?php

namespace App\Service;

use App\Models\ProductCate;


class ProductSearch
{
    // 初始化查询
    protected $params = [
        'index' => 'products',
        'type'  => '_doc',
        'body'  => [
            'query' => [
                'function_score' => [
                    'query' => [
                        'bool' => [
                            'filter' => [],
                            'must'   => [],
                        ],
                    ],
                    'field_value_factor' => [
                        'field' => 'sold_count',
                        'modifier' => 'log1p',
                        'factor' => 0.1
                    ]
                ],
            ],
        ],
    ];

    //分页查询
    public function paginate($size, $page)
    {
        $this->params['body']['from'] = ($page - 1) * $size;
        $this->params['body']['size'] = $size;

        return $this;
    }


    //筛选上架状态的商品
    public function onSale()
    {
        $this->params['body']['query']['function_score']['query']['bool']['filter'][] = ['term' => ['on_sale' => true]];

        return $this;
    }

    //筛选软删除状态的商品
    public function onDelete()
    {
        $this->params['body']['query']['function_score']['query']['bool']['filter'][] = ['term' => ['delete_at' => false]];

        return $this;
    }

    //按分类筛选商品
    public function category(ProductCate $category)
    {
        if ($category->is_directory) {
            $this->params['body']['query']['function_score']['query']['bool']['filter'][] = [
                'prefix' => ['category_path' => $category->path.$category->id.'-'],
            ];
        } else {
            $this->params['body']['query']['function_score']['query']['bool']['filter'][] = ['term' => ['product_cate_id' => $category->id]];
        }
        return $this;
    }

    //搜索词
    public function keywords($keywords)
    {
        // 如果参数不是数组则转为数组
        $keywords = is_array($keywords) ? $keywords : [$keywords];
        foreach ($keywords as $keyword) {
            $this->params['body']['query']['function_score']['query']['bool']['must'][] = [
                'multi_match' => [
                    'query'  => $keyword,
                    'type' => 'best_fields',
                    'tie_breaker' => 0.3,
                    'fields' => [
                        'title^3',
                        'long_title^2',
                        'category^2',
                        'description',
                        'skus_title'
                    ],
                ],
            ];
        }
        return $this;
    }

    // whereIn 查询
    public function whereIn($minPrice, $maxPrice)
    {
        if ($minPrice > 0 && $maxPrice > 0) {
            $this->params['body']['query']['function_score']['query']['bool']['filter'][] = [
                'range' => [
                    'price' => [
                        "gte" => $minPrice,
                        "lte" => $maxPrice
                    ],
                ],
            ];
        } else if ($minPrice > 0) {
            $this->params['body']['query']['function_score']['query']['bool']['filter'][] = [
                'range' => [
                    'price' => [
                        "gte" => $minPrice,
                    ],
                ],
            ];
        } else if ($maxPrice > 0) {
            $this->params['body']['query']['function_score']['query']['bool']['filter'][] = [
                'range' => [
                    'price' => [
                        "gte" => $maxPrice,
                    ],
                ],
            ];
        }

        return $this;
    }

//    // 添加一个按商品规格属性筛选的条件
//    public function propertyFilter($name, $value,  $type = 'filter')
//    {
//        $this->params['body']['query']['bool'][$type][] = [
//            'nested' => [
//                'path'  => 'properties',
//                'query' => [
//                    ['term' => ['skus.title' => $name.':'.$value]],
//                ],
//            ],
//        ];
//        return $this;
//    }

    // 设置 minimum_should_match 参数
//    public function minShouldMatch($count)
//    {
//        $this->params['body']['query']['bool']['minimum_should_match'] = (int)$count;
//
//        return $this;
//    }

    //排序
    public function orderBy($field, $direction)
    {
        if (!isset($this->params['body']['sort'])) {
            $this->params['body']['sort'] = [];
        }
        $this->params['body']['sort'][] = [
            $field => $direction
        ];
        return $this;
    }

    // 默认综合排序
    public function defaultOrderBy()
    {
        $this->params['body']['sort']['_script'] = [
            'script'=>"(doc['sold_count'].value * 100 + doc['sort'].value) + doc['created_diff_day'].value",
            'type'=>'number',
            "order"=>"desc"
        ];
        return $this;
    }

    //返回构造好的查询参数
    public function getParams()
    {
        return $this->params;
    }
}
